VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "StdFndPort"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
'******************************************************************
' Copyright (C) 2004, Intergraph Corporation. All rights reserved.
'
'File
'    StdFndPort.cls
'
'Author
'    RMP
'
'Description
'    USS Implementation for a "Standard" foundation port. Bolthole
'    coordinates are generated by the Symbol based on other inputs.
'    The number of outputs is "variable" because:
'       * For standard circular and rectangular patterns we have three
'           outputs : bolt holes curve, footprint curve, bounded plane
'       * For SingleHole and NoHole we only generate a plane bounded by
'           the footprint curve. (This is for V6, may change in the next release)
'
'   Change History:
'   dd.mmm.yyyy        who                           change description
'   -----------       -----                          ------------------
'  08.SEP.2006     KKC  DI-95670  Replace names with initials in all revision history sheets and symbols
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Option Explicit

Implements IJDUserSymbolServices

Dim m_outputColl As IJDOutputCollection
Private Const E_FAIL = -2147467259

Private Function IJDUserSymbolServices_EditOccurence(pSymbolOccurrence As Object, ByVal pTransactionMgr As Object) As Boolean
    IJDUserSymbolServices_EditOccurence = False
End Function

Private Function IJDUserSymbolServices_GetDefinitionName(ByVal definitionParameters As Variant) As String
    IJDUserSymbolServices_GetDefinitionName = "SP3DFoundationPorts.StdFndPort"
End Function

Private Sub IJDUserSymbolServices_InitializeSymbolDefinition(ppSymbolDefDisp As IMSSymbolEntities.IJDSymbolDefinition)
    ' Remove all previous Symbol Definition information
    ppSymbolDefDisp.IJDInputs.RemoveAllInput
    ppSymbolDefDisp.IJDRepresentations.RemoveAllRepresentation
    ppSymbolDefDisp.IJDRepresentationEvaluations.RemoveAllRepresentationEvaluations
    
    FeedPortDefinition ppSymbolDefDisp
End Sub

Private Function IJDUserSymbolServices_InstanciateDefinition(ByVal CodeBase As String, ByVal definitionParameters As Variant, ByVal pResourceMgr As Object) As Object
    Dim oSymbolFactory As IMSSymbolEntities.IJDSymbolEntitiesFactory
    Dim oSymbolDefinition As IMSSymbolEntities.DSymbolDefinition
    
    Set oSymbolFactory = New IMSSymbolEntities.DSymbolEntitiesFactory
    Set oSymbolDefinition = oSymbolFactory.CreateEntity(Definition, pResourceMgr)
    Set oSymbolFactory = Nothing
    
    IJDUserSymbolServices_InitializeSymbolDefinition oSymbolDefinition
    
    ' Set definition progId and codebase
    oSymbolDefinition.ProgId = "SP3DFoundationPorts.StdFndPort"
    oSymbolDefinition.CodeBase = CodeBase
    
    ' Give a unique name to the symbol definition
    oSymbolDefinition.Name = oSymbolDefinition.ProgId
    
    'return symbol defintion
    Set IJDUserSymbolServices_InstanciateDefinition = oSymbolDefinition
    Set oSymbolDefinition = Nothing
End Function

Private Sub IJDUserSymbolServices_InvokeRepresentation(ByVal pSymbolOccurrence As Object, ByVal pRepName As String, ByVal pOutputColl As Object, ByRef arrayOfInputs())
    Set m_outputColl = pOutputColl
    If StrComp(pRepName, "Physical") = 0 Then
        Symbolic arrayOfInputs
    End If
End Sub

'
' We are constructing the Foundation Port symbol "like" the pipe and HVAC nozzle symbols, so that
' the orientation semantic can consistently position all ports.
' However, if our bounded plane is chosen as the surface for creating an assembly constraint, the normal
' of this plane should be pointing away from the equipment.
' So the normals of our bounded planes should be along (-1, 0, 0)
'
Private Sub Symbolic(ByRef arrayOfInputs())
    On Error GoTo ErrorHandler
    Dim lFndType As Long
    Dim lNumberOfBoltholes As Long
    Dim dBoltCircleDiameter As Double
    Dim lNumHolesX As Long, lNumHolesY As Long
    Dim dXHolesDist As Double, dYHolesDist As Double
    Dim dFPOffset As Double, dFPCurveRadius As Double
    
    Dim lGeomPlacementType As Long
    lGeomPlacementType = 0
        
    Dim lsPoints(0 To 14) As Double
    
    Dim geomFactory As New IngrGeom3D.GeometryFactory
        
    lFndType = arrayOfInputs(1)
    lNumberOfBoltholes = arrayOfInputs(2)
    dBoltCircleDiameter = arrayOfInputs(3)
    lNumHolesX = arrayOfInputs(4)
    lNumHolesY = arrayOfInputs(5)
    dXHolesDist = arrayOfInputs(6)
    dYHolesDist = arrayOfInputs(7)
    dFPOffset = arrayOfInputs(8)
        
    Dim lLB1 As Long, lUB1 As Long
    lLB1 = LBound(arrayOfInputs())
    lUB1 = UBound(arrayOfInputs())
    If lUB1 = 9 Then
        lGeomPlacementType = arrayOfInputs(9)
    End If

        
    If dFPOffset = DBL_UNDEFINED Then
        dFPOffset = 0
    End If
        
    Dim oErrors As IJEditErrors
    Set oErrors = New IMSErrorLog.JServerErrors
    
    Dim oFootprintCurve As Object, oBoltholesCurve As Object
    Dim oPlane As IngrGeom3D.Plane3d
    
    If lFndType = 1 Then
        If lGeomPlacementType = 0 Then
            ' first construct the Boltholes linestring. Pass Zero for last two parameters
            FillPointsArray lsPoints, lNumHolesX, lNumHolesY, dXHolesDist, dYHolesDist, 0, 0
            Set oBoltholesCurve = geomFactory.LineStrings3d.CreateByPoints( _
                                                m_outputColl.ResourceManager, 5, lsPoints)
            ' construct footprint curve. Presently we have only one symbol parameter for the offset,
            ' pass it for the last two parameters
            FillPointsArray lsPoints, lNumHolesX, lNumHolesY, dXHolesDist, dYHolesDist, dFPOffset, dFPOffset
            Set oFootprintCurve = geomFactory.LineStrings3d.CreateByPoints( _
                                                m_outputColl.ResourceManager, 5, lsPoints)
        ElseIf lGeomPlacementType = 1 Then
            FillPointsArrayByCenter lsPoints, lNumHolesX, lNumHolesY, dXHolesDist, dYHolesDist, 0, 0
            Set oBoltholesCurve = geomFactory.LineStrings3d.CreateByPoints( _
                                                m_outputColl.ResourceManager, 5, lsPoints)
            FillPointsArrayByCenter lsPoints, lNumHolesX, lNumHolesY, dXHolesDist, dYHolesDist, dFPOffset, dFPOffset
            Set oFootprintCurve = geomFactory.LineStrings3d.CreateByPoints( _
                                                m_outputColl.ResourceManager, 5, lsPoints)
                                                    
        End If
    ElseIf lFndType = 2 Then
        Set oBoltholesCurve = geomFactory.Ellipses3d.CreateByCenterNormMajAxisRatio( _
                                    m_outputColl.ResourceManager, 0, 0, 0, _
                                    -1, 0, 0, _
                                    0, 0, dBoltCircleDiameter / 2, _
                                    1#)
        Set oFootprintCurve = geomFactory.Ellipses3d.CreateByCenterNormMajAxisRatio( _
                                    m_outputColl.ResourceManager, 0, 0, 0, _
                                    -1, 0, 0, _
                                    0, 0, dBoltCircleDiameter / 2 + dFPOffset, _
                                    1#)
    ElseIf lFndType = 3 Or lFndType = 4 Then
        ' single hole and no hole
        ' For V6, for the SingleHole and NoHole options, we just create a circular
        ' footprint curve with the footprint offset as radius
        dFPCurveRadius = dFPOffset
        If dFPCurveRadius <= 0 Then
            ' use hardcoded value.
            dFPCurveRadius = 0.1
        End If
        Set oFootprintCurve = geomFactory.Ellipses3d.CreateByCenterNormMajAxisRatio( _
                                    m_outputColl.ResourceManager, 0, 0, 0, _
                                    -1, 0, 0, _
                                    0, 0, dFPCurveRadius, _
                                    1#)
    End If
    
    If Not oFootprintCurve Is Nothing Then
        Set oPlane = geomFactory.Planes3d.CreateByOuterBdry(m_outputColl.ResourceManager, oFootprintCurve)
        m_outputColl.AddOutput "BoundedPlane", oPlane
        m_outputColl.AddOutput "FootprintCurve", oFootprintCurve
    End If
    
    If Not oBoltholesCurve Is Nothing Then
        m_outputColl.AddOutput "BoltHolesCurve", oBoltholesCurve
    End If
    
    Set oPlane = Nothing
    Set oBoltholesCurve = Nothing
    Set oFootprintCurve = Nothing
    
    Set geomFactory = Nothing
    Exit Sub
ErrorHandler:
    Err.Raise E_FAIL
End Sub


Private Sub FeedPortDefinition(pSymbolDefinition As IMSSymbolEntities.IJDSymbolDefinition)
  
    On Error GoTo ErrorHandler
    
    ' Create a new input by new operator
    Dim Inputs(0 To 8) As IMSSymbolEntities.IJDInput
    
    ' Create a defaultValue
    Dim PC As IMSSymbolEntities.IJDParameterContent
    Set PC = New IMSSymbolEntities.DParameterContent 'not persistent PC
    
    PC.Type = igValue
    
    Set Inputs(0) = New IMSSymbolEntities.DInput
    Inputs(0).Name = "FoundationPortType"
    Inputs(0).Description = "Type of the Foundation Port"
    Inputs(0).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 2 ' 2 stands for circular
    Inputs(0).DefaultParameterValue = PC
    
    Set Inputs(1) = New IMSSymbolEntities.DInput
    Inputs(1).Name = "NumberOfHoles"
    Inputs(1).Description = "Number of BoltHoles"
    Inputs(1).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 4
    Inputs(1).DefaultParameterValue = PC
    
    Set Inputs(2) = New IMSSymbolEntities.DInput
    Inputs(2).Name = "BoltCircleDiameter"
    Inputs(2).Description = "Diameter of the Bolt Circle"
    Inputs(2).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 0.5
    Inputs(2).DefaultParameterValue = PC
    
    Set Inputs(3) = New IMSSymbolEntities.DInput
    Inputs(3).Name = "NumHolesX"
    Inputs(3).Description = "Number of Holes in X"
    Inputs(3).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 2
    Inputs(3).DefaultParameterValue = PC
    
    Set Inputs(4) = New IMSSymbolEntities.DInput
    Inputs(4).Name = "NumHolesY"
    Inputs(4).Description = "Number of Holes in Y"
    Inputs(4).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 2
    Inputs(4).DefaultParameterValue = PC
    
    Set Inputs(5) = New IMSSymbolEntities.DInput
    Inputs(5).Name = "DistanceHolesX"
    Inputs(5).Description = "Distance between Holes in X"
    Inputs(5).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 0.5
    Inputs(5).DefaultParameterValue = PC
    
    Set Inputs(6) = New IMSSymbolEntities.DInput
    Inputs(6).Name = "DistanceHolesY"
    Inputs(6).Description = "Distance between Holes in Y"
    Inputs(6).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 0.5
    Inputs(6).DefaultParameterValue = PC
    
    Set Inputs(7) = New IMSSymbolEntities.DInput
    Inputs(7).Name = "FootprintOffset"
    Inputs(7).Description = "Offset of the Footprint"
    Inputs(7).Properties = igINPUT_IS_A_PARAMETER
    PC.UomValue = 0.1
    Inputs(7).DefaultParameterValue = PC
    
    Set Inputs(8) = New IMSSymbolEntities.DInput
    Inputs(8).Name = "GeometryPlacementType"
    Inputs(8).Description = "Geometry Placement Type"
    Inputs(8).Properties = igINPUT_IS_A_PARAMETER Or igDESCRIPTION_OPTIONAL
    PC.UomValue = 0
    Inputs(8).DefaultParameterValue = PC
    
    'Set the input to the definition
    Dim InputsIf As IMSSymbolEntities.IJDInputs
    Set InputsIf = pSymbolDefinition
    
    Dim index As Integer
    For index = 0 To 7
      InputsIf.SetInput Inputs(index), index + 1
    Next
    
    If Inputs(8).IsPropertySet(igDESCRIPTION_OPTIONAL) Then
        InputsIf.SetInput Inputs(index), index + 1
    End If
    
    
    'Define the representation "Symbolic"
    Dim rep1 As IMSSymbolEntities.IJDRepresentation
    Set rep1 = New IMSSymbolEntities.DRepresentation
    
    rep1.Name = "Physical"
    rep1.Description = "Physical Representation of Port"
    rep1.Properties = igREPRESENTATION_ISVBFUNCTION
    ' The number of outputs is variable
    rep1.Properties = igCOLLECTION_VARIABLE
    rep1.RepresentationId = SimplePhysical
    
    Dim oRep1Outputs As IMSSymbolEntities.IJDOutputs
    Set oRep1Outputs = rep1
        
    'Set the 'Physical' representation to definition
    Dim RepsIf As IMSSymbolEntities.IJDRepresentations
    Set RepsIf = pSymbolDefinition
    RepsIf.SetRepresentation rep1
    
    Set rep1 = Nothing
    Set RepsIf = Nothing
    Set oRep1Outputs = Nothing
    
    'Define the evaluation for the Physical representation
    Dim SymbolicRepEval As IJDRepresentationEvaluation
    Set SymbolicRepEval = New DRepresentationEvaluation
    SymbolicRepEval.Name = "Physical"
    SymbolicRepEval.Description = "Physical representation of Foundation Port"
    SymbolicRepEval.Properties = igREPRESENTATION_HIDDEN
    SymbolicRepEval.Type = igREPRESENTATION_VBFUNCTION
    SymbolicRepEval.ProgId = "SP3DFoundationPorts.StdFndPort"
    
    'Set the evaluations on symbol definition
    Dim RepsEvalsIf As IMSSymbolEntities.IJDRepresentationEvaluations
    Set RepsEvalsIf = pSymbolDefinition
    
    RepsEvalsIf.AddRepresentationEvaluation SymbolicRepEval
    
    Set RepsEvalsIf = Nothing
    Set SymbolicRepEval = Nothing
    
    Exit Sub
ErrorHandler:
    Error.Raise E_FAIL
End Sub


'
' Note that the sequence of the points determines the normal of the plane
' that is generated with this linestring as boundary. We want our
' plane normals to be pointing "away" from the equipment, which is the
' direction of the "X" axis of the symbol.
'
Private Sub FillPointsArray(lsPoints() As Double, lNumHolesX As Long, _
                lNumHolesY As Long, dHolesDistX As Double, _
                dHolesDistY As Double, dFPOffsetX As Double, dFPOffsetY As Double)

    Dim dMinZ As Double, dMaxZ As Double, dMinY As Double, dMaxY As Double
    
    dMinY = 0 - dFPOffsetY
    dMinZ = 0 - dFPOffsetX
    dMaxY = ((lNumHolesY - 1) * dHolesDistY) + dFPOffsetY
    dMaxZ = ((lNumHolesX - 1) * dHolesDistX) + dFPOffsetX

    lsPoints(0) = 0
    lsPoints(1) = dMinY
    lsPoints(2) = dMinZ

    lsPoints(3) = 0
    lsPoints(4) = dMinY
    lsPoints(5) = dMaxZ

    lsPoints(6) = 0
    lsPoints(7) = dMaxY
    lsPoints(8) = dMaxZ

    lsPoints(9) = 0
    lsPoints(10) = dMaxY
    lsPoints(11) = dMinZ

    lsPoints(12) = 0
    lsPoints(13) = dMinY
    lsPoints(14) = dMinZ

End Sub

Private Sub FillPointsArrayByCenter(lsPoints() As Double, lNumHolesX As Long, _
                lNumHolesY As Long, dHolesDistX As Double, _
                dHolesDistY As Double, dFPOffsetX As Double, dFPOffsetY As Double)

    Dim dMinZ As Double, dMaxZ As Double, dMinY As Double, dMaxY As Double

    dMinY = -(((lNumHolesY - 1) * dHolesDistY) + 2 * dFPOffsetY) / 2
    dMinZ = -(((lNumHolesX - 1) * dHolesDistX) + 2 * dFPOffsetX) / 2
    dMaxY = (((lNumHolesY - 1) * dHolesDistY) + 2 * dFPOffsetY) / 2
    dMaxZ = (((lNumHolesX - 1) * dHolesDistX) + 2 * dFPOffsetX) / 2

    lsPoints(0) = 0
    lsPoints(1) = dMinY
    lsPoints(2) = dMinZ

    lsPoints(3) = 0
    lsPoints(4) = dMinY
    lsPoints(5) = dMaxZ

    lsPoints(6) = 0
    lsPoints(7) = dMaxY
    lsPoints(8) = dMaxZ

    lsPoints(9) = 0
    lsPoints(10) = dMaxY
    lsPoints(11) = dMinZ

    lsPoints(12) = 0
    lsPoints(13) = dMinY
    lsPoints(14) = dMinZ

End Sub

